/**
 * v-clipboard 文字复制剪贴
 * Copyright (c) 2021 cj
 */

import Clipboard from 'clipboard'
import type { Directive, DirectiveBinding } from 'vue'

interface ClipboardElement extends HTMLElement {
  _vClipBoard?: Clipboard
  _vClipBoard_success?: (e: Clipboard.Event) => void
  _vClipBoard_error?: (e: Clipboard.Event) => void
}

export default {
  mounted(el: ClipboardElement, binding: DirectiveBinding) {
    switch (binding.arg) {
      case 'success':
        el._vClipBoard_success = binding.value
        break
      case 'error':
        el._vClipBoard_error = binding.value
        break
      default: {
        const clipboard = new Clipboard(el, {
          text: () => binding.value,
          action: () => (binding.arg === 'cut' ? 'cut' : 'copy'),
        })
        clipboard.on('success', (e) => {
          const callback = el._vClipBoard_success
          if (callback) callback(e)
        })
        clipboard.on('error', (e) => {
          const callback = el._vClipBoard_error
          if (callback) callback(e)
        })
        el._vClipBoard = clipboard
      }
    }
  },
  updated(el: ClipboardElement, binding: DirectiveBinding) {
    if (binding.arg === 'success') {
      el._vClipBoard_success = binding.value
    } else if (binding.arg === 'error') {
      el._vClipBoard_error = binding.value
    } else {
      // Fix: Destroy and recreate clipboard instance instead of trying to modify text property
      if (el._vClipBoard) {
        el._vClipBoard.destroy()
        const clipboard = new Clipboard(el, {
          text: () => binding.value,
          action: () => (binding.arg === 'cut' ? 'cut' : 'copy'),
        })
        clipboard.on('success', (e) => {
          const callback = el._vClipBoard_success
          if (callback) callback(e)
        })
        clipboard.on('error', (e) => {
          const callback = el._vClipBoard_error
          if (callback) callback(e)
        })
        el._vClipBoard = clipboard
      }
    }
  },
  unmounted(el: ClipboardElement) {
    if (!el._vClipBoard) return
    if (el._vClipBoard_success) {
      delete el._vClipBoard_success
    } else if (el._vClipBoard_error) {
      delete el._vClipBoard_error
    } else {
      el._vClipBoard!.destroy()
      delete el._vClipBoard
    }
  },
} as Directive
